#include "bmp.h"
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
int GetBmpRGBData(const char*filename,unsigned char*data){
	FILE*fp=fopen(filename,"rb");	
	BITMAPFILEHEADER bfh={0};
	BITMAPINFOHEADER bih={0};
	if (fp==NULL)return -1;
	fread(&bfh,sizeof(bfh),1,fp);
	fread(&bih,sizeof(bih),1,fp);
	fseek(fp,bfh.bfOffBits,SEEK_SET);
	if (bih.biSizeImage==0)
		bih.biSizeImage=bih.biHeight*GetWidthBytes(bih.biWidth,bih.biBitCount);
	fread(data,1,bih.biSizeImage,fp);
	fclose(fp);
	return 0;
}

int GetBmpInfo(const char*filename,int*width,int*height,int*bits){
	FILE*fp=fopen(filename,"rb");	
	BITMAPFILEHEADER bfh={0};
	BITMAPINFOHEADER bih={0};
	if (fp==NULL)return -1;
	fread(&bfh,sizeof(bfh),1,fp);
	fread(&bih,sizeof(bih),1,fp);
	fclose(fp);
	*width=bih.biWidth;
	*height=bih.biHeight;
	*bits=bih.biBitCount;
	return 0;
}

int GetWidthBytes(int width,int bits){
	int widthbytes=width*bits/8;
	if (widthbytes%4!=0){
		widthbytes=(widthbytes/4+1)*4;
	}
	return widthbytes;
}
int SaveBmp(const char*filename,unsigned char*data,int width,int height,int bits){
	FILE*fp=NULL;
	BITMAPFILEHEADER bfh={0};
	BITMAPINFOHEADER bih={0};
	DWORD datasize=height*GetWidthBytes(width,bits);
	if(filename!=NULL){
	   fp=fopen(filename,"wb");
	}else{
	   char tempname[256]={0};
	   sprintf(tempname,"%d_%d.bmp",time(NULL),rand());
	   fp=fopen(tempname,"wb");
	}
	if (fp==NULL)return -1;	
	bfh.bfType=MAKEWORD('B','M');
	bfh.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
	bfh.bfSize=bfh.bfOffBits+datasize;

	bih.biSize=sizeof(BITMAPINFOHEADER);
	bih.biBitCount=bits;
	bih.biWidth=width;
	bih.biHeight=height;
	bih.biSizeImage=datasize;
	bih.biPlanes=1;
	bih.biCompression=BI_RGB;

	fwrite(&bfh,sizeof(BITMAPFILEHEADER),1,fp);
	fwrite(&bih,sizeof(BITMAPINFOHEADER),1,fp);	
	fwrite(data,1,datasize,fp);

	fclose(fp);
	return 0;
}

int GetScreenInfo(int*width,int*height,int*bits){
//	width=GetSystemMetrics(SM_CXSCREEN);//包括任务栏
//	height=GetSystemMetrics(SM_CYSCREEN);
//	width=GetSystemMetrics(SM_CXFULLSCREEN);//不包括任务栏
//	height=GetSystemMetrics(SM_CYFULLSCREEN);
	HDC hDC=CreateDC("DISPLAY",NULL,NULL,NULL);
	*bits=GetDeviceCaps(hDC,BITSPIXEL);
	*width=GetDeviceCaps(hDC,HORZRES);
	*height=GetDeviceCaps(hDC,VERTRES);
	DeleteDC(hDC);
	return 0;
}
//获取屏幕数据
int GetScreenRGBData(unsigned char*data){
	HDC hDC=CreateDC("DISPLAY",NULL,NULL,NULL);
	int bits=GetDeviceCaps(hDC,BITSPIXEL);
	int width=GetDeviceCaps(hDC,HORZRES);
	int height=GetDeviceCaps(hDC,VERTRES);
	HBITMAP hMemBMP;
	HDC hMemDC;
	BITMAPINFOHEADER bih={0};
	hMemBMP=CreateCompatibleBitmap(hDC,width,height);
	hMemDC=CreateCompatibleDC(hDC);
	SelectObject(hMemDC,hMemBMP);
	BitBlt(hMemDC,0,0,width,height,hDC,0,0,SRCCOPY);
	if (bits<24)bits=24;	
	bih.biSize=sizeof(BITMAPINFOHEADER);
	bih.biBitCount=bits;	
	bih.biClrImportant=BI_RGB;
	bih.biPlanes=1;
	bih.biHeight=height;
	bih.biWidth=width;
	bih.biSizeImage=height*GetWidthBytes(width,bits);
	GetDIBits(hMemDC,hMemBMP,0,height,data,(LPBITMAPINFO)&bih,DIB_RGB_COLORS);	

	DeleteDC(hMemDC);
	DeleteObject(hMemBMP);
//	ReleaseDC(WindowFromDC(hDC),hDC);
	DeleteDC(hDC);
	return 0;
}

int ShowBmp(HWND hWnd,unsigned char*data,int width,int height,int bits){
	HDC hDC=GetWindowDC(hWnd);
	HDC tempDC=NULL;
	HBITMAP tempbmp=NULL;
	BITMAPINFOHEADER bih={0};
	int ClientWidth=0;
	int ClientHeight=0;
    int x=0,y=0;
    RECT WindowRect;  
    RECT ClientRect;  
    GetWindowRect(hWnd, &WindowRect);  
    GetClientRect(hWnd, &ClientRect);
	RealizePalette(hDC);
	SetStretchBltMode(hDC,COLORONCOLOR);
	ClientWidth=ClientRect.right-ClientRect.left;
	ClientHeight=ClientRect.bottom-ClientRect.top;
//以左右下间距相等为前提
    x=((WindowRect.right-WindowRect.left)-(ClientRect.right-ClientRect.left))/2;
    y=(WindowRect.bottom-WindowRect.top)-(ClientRect.bottom-ClientRect.top)-x;
    
	tempDC=CreateCompatibleDC(hDC);
	tempbmp=CreateCompatibleBitmap(hDC,ClientWidth,ClientHeight);
	SelectObject(tempDC,tempbmp);
	
	bih.biSize=sizeof(BITMAPINFOHEADER);
	bih.biBitCount=bits;
	bih.biPlanes=1;
	bih.biSizeImage=height*GetWidthBytes(width,bits);
	bih.biHeight=height;
	bih.biWidth=width;	
	bih.biClrImportant=BI_RGB;

	StretchDIBits(tempDC,0,0,ClientWidth,ClientHeight,
		0,0,width,height,data,(LPBITMAPINFO)&bih,
		DIB_RGB_COLORS,SRCCOPY);
	BitBlt(hDC,x,y,ClientWidth,ClientHeight,tempDC,0,0,SRCCOPY);

	DeleteDC(tempDC);
	DeleteObject(tempbmp);
	ReleaseDC(hWnd,hDC);
	return 0;
}
int RGBChangeRGColor(unsigned char*pScr,int width,int height,int bits){
	int step=bits/8;
	int w,h;
	unsigned char*p;
	unsigned char temp;
	int widthbytes=GetWidthBytes(width,bits);
	for(h=0;h<height;h++){
		p=pScr+widthbytes*h;
		for (w=0;w<width;w++){
			temp=p[0];
			p[0]=p[1];
			p[1]=temp;
			p+=step;
		}
	}
	return 0;
}

int RGBChangeRBColor(unsigned char*pScr,int width,int height,int bits){
	int step=bits/8;
	int w,h;
	unsigned char*p;
	unsigned char temp;
	int widthbytes=GetWidthBytes(width,bits);
	for(h=0;h<height;h++){
		p=pScr+widthbytes*h;
		for (w=0;w<width;w++){
			temp=p[0];
			p[0]=p[2];
			p[2]=temp;
			p+=step;
		}
	}
	return 0;
}
int RGBChangeGBColor(unsigned char*pScr,int width,int height,int bits){
	int step=bits/8;
	int w,h;
	unsigned char*p;
	unsigned char temp;
	int widthbytes=GetWidthBytes(width,bits);
	for(h=0;h<height;h++){
		p=pScr+widthbytes*h;
		for (w=0;w<width;w++){
			temp=p[1];
			p[1]=p[2];
			p[2]=temp;
			p+=step;
		}
	}
	return 0;
}
int RGBChangeUD(unsigned char*pScr,int width,int height,int bits){
	int step=bits/8;
//	int w;
	int h;
	unsigned char*p;
	unsigned char*q;
	unsigned char*temp;
	int widthbytes=GetWidthBytes(width,bits);
	temp=(unsigned char*)malloc(widthbytes);
	for(h=0;h<height/2;h++){
		p=pScr+widthbytes*h;
		q=pScr+widthbytes*(height-h-1);
		memcpy(temp,p,widthbytes);
		memcpy(p,q,widthbytes);
		memcpy(q,temp,widthbytes);
	}
	free(temp);
	return 0;
}
int RGBChangeLR(unsigned char*pScr,int width,int height,int bits){
	int step=bits/8;
	int w,h;
	unsigned char*p;
	unsigned char*q;
	unsigned char*temp;
	int widthbytes=GetWidthBytes(width,bits);
	temp=(unsigned char*)malloc(step);
	for(h=0;h<height;h++){
		p=pScr+widthbytes*h;
		q=pScr+widthbytes*h+(width-1)*step;
		for (w=0;w<width/2;w++){
			memcpy(temp,p,step);
			memcpy(p,q,step);
			memcpy(q,temp,step);
			p+=step;
			q-=step;
		}
	}
	free(temp);
	return 0;
}
int RGBChangeLRUD(unsigned char*pScr,int width,int height,int bits){
	int step=bits/8;
	int w,h;
	unsigned char*p;
	unsigned char*q;
	unsigned char*temp;
	int widthbytes=GetWidthBytes(width,bits);
	temp=(unsigned char*)malloc(step);
	for(h=0;h<height/2;h++)	{
		p=pScr+widthbytes*h;
		q=pScr+widthbytes*(height-h-1)+(width-1)*step;
		for (w=0;w<width;w++){
			memcpy(temp,p,step);
			memcpy(p,q,step);
			memcpy(q,temp,step);
			p+=step;
			q-=step;
		}
	}
	free(temp);
	return 0;
}
int RGB32toRGB24(unsigned char*pScr,unsigned char*pDes,int width,int height){
	int widthbytes32=GetWidthBytes(width,32);
	int widthbytes24=GetWidthBytes(width,24);
	int step32=4;
	int step24=3;
	unsigned char *p32,*p24;
	int w,h;
	for(h=0;h<height;h++){
		p32=pScr+widthbytes32*h;
		p24=pDes+widthbytes24*h;
		for (w=0;w<width;w++){
			p24[0]=p32[0];
			p24[1]=p32[1];
			p24[2]=p32[2];
			p24+=step24;
			p32+=step32;
		}
	}
	return 0;
}
int RGB24toRGB32(unsigned char*pScr,unsigned char*pDes,int width,int height){
	int widthbytes32=GetWidthBytes(width,32);
	int widthbytes24=GetWidthBytes(width,24);
	int step32=4;
	int step24=3;
	unsigned char *p32,*p24;
	int w,h;
	for(h=0;h<height;h++){
		p32=pDes+widthbytes32*h;
		p24=pScr+widthbytes24*h;
		for (w=0;w<width;w++){
			p32[0]=p24[0];
			p32[1]=p24[1];
			p32[2]=p24[2];
			p24+=step24;
			p32+=step32;
		}
	}
	return 0;
}